﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using NotWindowsStore.Models;

namespace NotWindowsStore.Controllers
{
    public class AppController : Controller
    {
        [Authorize]
        public ActionResult Create()
        {
            using (var ctx = new notwindowsentities())
            {
                LoadLookups(ctx);

                return View();
            }
        }

        [Authorize]
        [HttpPost]
        public ActionResult Create(AppViewModel model)
        {
            using (var ctx = new notwindowsentities())
            {
                LoadLookups(ctx);
                if (!ModelState.IsValid)
                {
                    return View();
                }

                NwsApp app = new NwsApp
                {
                    UploadDate = DateTime.Now,
                    DownloadCount = 0
                };
                app.UpdateFromViewModel(model);
                string temp;
                app.AppX = FileToBytes("AppX", out temp);
                app.AppXFileName = temp;
                app.AuthorUserId = ctx.NwsUsers.First(u => u.UserName == User.Identity.Name).UserId;
                app.Cer = FileToBytes("Cer", out temp);
                app.CerFileName = temp;
                string imageFileName;
                app.Image = ToPng(FileToBytes("Image", out imageFileName));
                ctx.NwsApps.AddObject(app);
                ctx.SaveChanges();

                return RedirectToAction("Index", "Home");
            }
        }

        private byte[] ToPng(byte[] imageBytes)
        {
            var bm = new Bitmap(new MemoryStream(imageBytes));
            var results = new MemoryStream();
            bm.Save(results, ImageFormat.Png);
            return results.ToArray();
        }

        private byte[] FileToBytes(string parameterName, out string appXFileName)
        {
            var file = Request.Files[parameterName];
            if (file == null)
            {
                throw new Exception("Could not find parameter " + parameterName);
            }
            appXFileName = Path.GetFileName(file.FileName);
            MemoryStream result = new MemoryStream();
            int read;
            byte[] buffer = new byte[1024];
            while ((read = file.InputStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                result.Write(buffer, 0, read);
            }
            return result.ToArray();
        }

        private void LoadLookups(notwindowsentities ctx)
        {
            ViewBag.Categories = ctx.NwsCategories
                .OrderBy(c => c.Title)
                .ToList()
                .Select(c =>
                new SelectListItem
                {
                    Value = c.CategoryId.ToString(),
                    Text = c.Title
                }).ToList();
        }

        public ActionResult Index()
        {
            using (var ctx = new Models.notwindowsentities())
            {
                return Json(ctx.NwsApps.Select(m =>
                    new
                    {
                        App = m,
                        User = m.NwsUser,
                        Category = m.NwsCategory
                    })
                    .ToList()
                    .Select(m => new
                    {
                        m.App.AppId,
                        m.App.AppName,
                        Category = m.Category.Title,
                        m.App.Description,
                        m.App.CategoryId,
                        UploadDate = m.App.UploadDate.ToString("d"),
                        m.App.DownloadCount,
                        m.User.UserName
                    })
                    , JsonRequestBehavior.AllowGet);
            }
        }

        public ActionResult Image(int id)
        {
            using (var ctx = new Models.notwindowsentities())
            {
                var image = ctx.NwsApps.First(i => i.AppId == id).Image;
                Response.ContentType = "image/png";
                Response.BinaryWrite(image);
                return null;
            }
        }

        public ActionResult Appx(int id)
        {
            using (var ctx = new Models.notwindowsentities())
            {
                var app = ctx.NwsApps.First(i => i.AppId == id);
                Response.ContentType = "binary/octet-stream";
                Response.AddHeader("Content-Disposition", "attachment; filename=\"" + app.AppXFileName + "\"");
                Response.BinaryWrite(app.AppX);

                app.DownloadCount++;
                ctx.SaveChanges();

                return null;
            }
        }

        public ActionResult Cer(int id)
        {
            using (var ctx = new Models.notwindowsentities())
            {
                var app = ctx.NwsApps.First(i => i.AppId == id);
                Response.ContentType = "binary/octet-stream";
                Response.AddHeader("Content-Disposition", "attachment; filename=\"" + app.CerFileName + "\"");
                Response.BinaryWrite(app.Cer);
                return null;
            }
        }
    }
}
